﻿using System.Collections.Generic;
using System.Linq;
using System.Windows;
using NUnit.Framework;

namespace Utility3D
{
    [TestFixture]
    public class ShapeTest
    {
        [Test]
        public void CanCloseShape()
        {
            var worldModel = DefaultWorldModelGenerator.GetModel();
            var drawingSurface = worldModel.DrawingSurfaceChains.First();

            var p1 = worldModel.Collections.AddPoint(drawingSurface, new Point(10, 90));
            var p2 = worldModel.Collections.AddPoint(drawingSurface, new Point(20, 80));

            var lineStroke = worldModel.Collections.AddStroke<LineStroke>(p1, p2);
            lineStroke.BreakAtPoint(drawingSurface, new Point(15, 85));

            var shape = worldModel.ShapeFromPointRef(p1).Single();

            Assert.AreEqual(2, worldModel.Strokes.Count());
            Assert.IsFalse(worldModel.Strokes.OfType<LineStroke>().Any(s => s.Start == p1 && s.End == p2));
            shape.Close();

            Assert.AreEqual(3, worldModel.Strokes.Count());
            Assert.IsTrue(worldModel.Strokes.OfType<LineStroke>().Any(s => s.Start == p1 && s.End == p2));
        }
    }

    public class Shape
    {
        private readonly List<Stroke> _strokes = new List<Stroke>();
        public ICollection<Stroke> Strokes { get { return _strokes; } }

        public WorldModel WorldModel { get; set; }

        public void Close()
        {
            if (_strokes.Count < 2) return;

            var pointsToLink = _strokes
                .OfType<LineStroke>()
                .Select(s => new KeyValuePair<IPointRef, LineStroke>(s.Start, s))
                .Concat(_strokes
                            .OfType<LineStroke>()
                            .Select(s => new KeyValuePair<IPointRef, LineStroke>(s.End, s)))
                .GroupBy(keyValuePair => keyValuePair.Key)
                .Where(g => g.Count() == 1)
                .ToList();

            if (pointsToLink.Count != 2) return;
            WorldModel.Collections.AddStroke<LineStroke>(pointsToLink.First().Key, pointsToLink.Last().Key, s => s.Shape = this);
        }
    }
}